<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-10-06
 * Time: 11:19
 */

namespace app\common\model;


use app\api\model\op\v1\WXMPShopRequestData;
use app\common\enum\WXMPShopOrderStatus;
use app\common\exception\WxMpShopException;

class MpShopOrder extends BaseModel
{

    protected $autoWriteTimestamp = false;

    /**
     * 对取出的订单价格进行分元转换处理
     * @param $value
     * @param $data
     * @return float|int
     */
    public function getOrderPriceAttr($value, $data)
    {
        if (empty($value)) {
            return 0;
        } else {
            return intval($value) / 100;
        }
    }

    /**
     * 处理创建时间（字符串转时间戳）
     * @param $value
     * @param $data
     * @return false|int
     */
    public function setCreateTimeAttr($value, $data)
    {
        if (empty($value)) {
            return '';
        } else {
            return strtotime(trim($value));
        }
    }

    /**
     * 处理创建时间（时间戳转字符串）
     * @param $value
     * @param $data
     * @return false|string
     */
    public function getCreateTimeAttr($value, $data)
    {
        if (empty($value)) {
            return '';
        } else {
            return date('Y-m-d H:i:s', intval($value));
        }
    }

    /**
     * 处理支付时间（字符串转时间戳）
     * @param $value
     * @param $data
     * @return false|int
     */
    public function setPayTimeAttr($value, $data)
    {
        if (empty($value)) {
            return '';
        } else {
            return strtotime(trim($value));
        }
    }

    /**
     * 处理支付时间（时间戳转字符串）
     * @param $value
     * @param $data
     * @return false|string
     */
    public function getPayTimeAttr($value, $data)
    {
        if (empty($value)) {
            return '';
        } else {
            return date('Y-m-d H:i:s', intval($value));
        }
    }

    /**
     * 将priduct_id json化
     * @param $value
     * @param $data
     * @return false|string
     */
    public function setProductIdsAttr($value, $data)
    {
        if (empty($value)) {
            return json_encode([], JSON_UNESCAPED_UNICODE);
        } else {
            $value = array_unique($value);
            $value = array_values($value);
            return json_encode($value, JSON_UNESCAPED_UNICODE);
        }
    }

    /**
     * 将priduct_id 解json变成数组
     * @param $value
     * @param $data
     * @return false|string
     */
    public function getProductIdsAttr($value, $data)
    {
        if (empty($value)) {
            return [];
        } else {
            return json_decode($value, true);
        }
    }

    public function user()
    {
        return $this->belongsTo('WeChatUser','openid','openid')
            ->field(['nick_name','openid']);
    }

    /**
     * 获取微信小商店订单的分页数据
     * @param array $params
     * @return \think\Paginator
     */
    public static function getPaginationList(array $params)
    {
        static::validatePaginationData($params);

        $static = new static();
        $static = $static->with(['user']);

        foreach ($params as $name => $value) {
            $value = !is_array($value) ? trim($value) : $value;
            switch ($name) {
                case 'transaction_id':
                    if (!empty($value)) {
                        $like_text = '%' . $value . '%';
                        $static = $static->whereLike('transaction_id', $like_text);
                    }
                    break;
                case 'status':
                    if (!empty($value)) {
                        $static = $static->where('status', '=', intval($value));
                    }
                    break;
            }
        }

        return $static
            ->paginate([
                'page' => $params['page'],
                'list_rows' => $params['limit']
            ], false);
    }

    /**
     * 从微信服务器获取数据到本地服务器的数据库中
     */
    public static function updateOrderFormWX()
    {
        $static = new static();
        $static->startTrans();

        $sql_data = [];
        try {

            // 先清空旧数据
            $static->whereRaw('1=1')
                ->delete();

            // 获取微信服务器的数据
            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::ALL));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::PEND_PAY));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::PEND_SHIP));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::PEND_RECEIVE));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::COMPLETE));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::AFTER_SALES_CANCEL));
//            $sql_data = array_merge($sql_data, self::getOrderDataWithStatus(WXMPShopOrderStatus::ACTIVE_CANCEL));

            $static->saveAll($sql_data);

            $static->commit();
        } catch (\Exception  $e) {
            $static->rollback();
            throw new \Exception($e->getMessage(),$e->getCode());
//            return false;
        }

        return true;
    }

    /**
     * 根据产品id检查对应的订单状态
     * @param $product_id
     * @param $status
     * @return bool
     */
    public static function checkOrderStatusByProductID($product_id, $status)
    {
        $flag = self::_checkOrderStatusByProductID($product_id, $status);

        // 如果没有找到，则更新一下数据后在查找
        if ($flag === false) {
            try {
                self::updateOrderFormWX();
            } catch (\Exception $e) {
                throw new WxMpShopException([
                    'errorCode' => 40202,
                    'msg' => '获取微信小商店订单数据异常',
                    'code' => 400
                ]);
            }

            return self::_checkOrderStatusByProductID($product_id, $status);
        }

        return $flag;
    }

    /**
     * 根据不同状态获取不同的数据
     * @param $status
     */
    private static function getOrderDataWithStatus($status)
    {
        $page = 1;
        $page_size = 10;

        $save_data = [];
        do {
            $wx_server_data = (new WXMPShopRequestData('order'))->getOrderList($page, $page_size, $status);
            foreach ($wx_server_data['order'] as $order_data) {
                $product_infos = $order_data['order_detail']['product_infos'];
                // 处理title
                $title = '';
                if (count($product_infos) > 1) {
                    $title = $product_infos[0]['title'] . '等' . count($product_infos) . '件商品';
                } else {
                    $title = $product_infos[0]['title'];
                }

                // 记录product_id（存在多个商品）
                $product_ids = array_column($product_infos, 'product_id');

                $save_data[] = [
                    'order_id' => $order_data['order_id'],
                    'openid' => $order_data['openid'],
                    'title' => $title,
                    'product_ids' => $product_ids,
                    'order_price' => $order_data['order_detail']['price_info']['order_price'],
                    'prepay_id' => isset($order_data['order_detail']['pay_info']['prepay_id']) ? $order_data['order_detail']['pay_info']['prepay_id'] : '',
                    'transaction_id' => $order_data['order_detail']['pay_info']['transaction_id'],
                    'status' => $order_data['status'],
                    'create_time' => $order_data['create_time'],
                    'pay_time' => isset($order_data['order_detail']['pay_info']['pay_time']) ? $order_data['order_detail']['pay_info']['pay_time'] : ''
                ];
            }
            $page++;
        } while(!empty($wx_server_data['order']));

        return $save_data;
    }

    /**
     * 根据产品id检查对应的订单状态
     * @param $product_id
     * @param $status
     * @return bool
     */
    private static function _checkOrderStatusByProductID($product_id, $status)
    {
        // 获取当前登录用户的openid
        $openid = MpApiUserToken::getCurrentTokenVar('openid');

        // 判断是否存在
        $product_id_where_exp = [];
        $product_id_where_exp[] = ['product_ids','like','['.$product_id.',%'];
        $product_id_where_exp[] = ['product_ids','like','%,'.$product_id.']'];
        $product_id_where_exp[] = ['product_ids','like','%,'.$product_id.',%'];
        $product_id_where_exp[] = ['product_ids','like','['.$product_id.']'];

        $mp_order = static::where([['openid','=',$openid],['status', '=', $status]])
            ->where(function ($query) use ($product_id_where_exp) {
                $query->whereOr($product_id_where_exp);
            })
            ->find();

        if (!$mp_order) {
            return false;
        }

        return $mp_order->order_id;
    }
}